import AdmZip from 'adm-zip'
import crypto from 'crypto'
import fs from 'fs'
import fse from 'fs-extra'
import path from 'path'

export function calcSha512(filePath: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const hash = crypto.createHash('sha512')
    const readStream = fs.createReadStream(filePath)
    readStream.pipe(hash)
    readStream.on('end', () => {
      const sha512Hash = hash.digest('hex')
      resolve(sha512Hash)
    })
    readStream.on('error', (err) => {
      reject(err)
    })
  })
}

export async function safeExtractAll(zipFilePath: string, outputDir: string, logger?: any) {
  if (fs.existsSync(outputDir)) {
    logger?.info?.(`Removing existing folder: ${outputDir}`)
    await fse.remove(outputDir)
  }
  await fse.mkdir(outputDir, { recursive: true })

  const zip = new AdmZip(zipFilePath)
  const entries = zip.getEntries()

  for (const entry of entries) {
    const rawName = entry.rawEntryName
    const entryName = Buffer.from(rawName).toString('utf8') // 处理中文
    const fullPath = path.join(outputDir, entryName)
    try {
      if (entry.isDirectory) {
        fs.mkdirSync(fullPath, { recursive: true })
      } else {
        fs.mkdirSync(path.dirname(fullPath), { recursive: true })
        fs.writeFileSync(fullPath, entry.getData())
      }

      try {
        fs.chmodSync(fullPath, 0o755)
      } catch (chmodErr: any) {
        logger?.warn?.(`chmod failed on ${fullPath}: ${chmodErr.message}`)
      }
    } catch (err: any) {
      logger?.error?.(`❌ Failed to extract ${entryName}: ${err.message}`)
    }
  }
}

// export async function unzipWithExtractZip(zipPath: string, destPath: string, logger?: any) {
//   try {
//     if (fs.existsSync(destPath)) {
//       logger?.info?.(`Removing existing folder: ${destPath}`)
//       await fse.remove(destPath)
//     }

//     logger?.info?.(`Extracting ${zipPath} to ${destPath}...`)
//     await extract(zipPath, { dir: destPath })
//     logger?.info?.('✅ Extraction complete')
//   } catch (err: any) {
//     logger?.error?.(`❌ Extraction failed: ${err.message}`)
//     throw err
//   }
// }
